﻿using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace StockControl
{
    public class StockBitbltControl : Control
    {
        public event BitbltPanelDrawEventHandler Draw;

        private bool _enableDrawing = false;

        public bool EnableDrawing
        {
            get { return this._enableDrawing; }
            set
            {
                if (this._enableDrawing)
                {
                    this.Restore();
                }

                if (!value)
                {
                    if (bitmapOld != null)
                    {
                        bitmapOld.Dispose();
                        bitmapOld = null;
                    }
                    if (bitmapNew != null)
                    {
                        bitmapNew.Dispose();
                        bitmapNew = null;
                    }
                    locationLast = Point.Empty;
                }

                this._enableDrawing = value;
            }
        }

        public StockBitbltControl()
            : base()
        {
            Visible = false;
        }

        Bitmap bitmapOld = null;
        Bitmap bitmapNew = null;
        Point locationLast = Point.Empty;

        protected override void OnLocationChanged(EventArgs e)
        {
            MoveTo(this.Location);
        }

        public void Restore()
        {
            using (Graphics g = Parent.CreateGraphics())
            {
                if (bitmapOld != null)
                {
                    // 在原位置恢复位图
                    g.DrawImage(bitmapOld, locationLast);
                }
            }
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr GetForegroundWindow();

        public void MoveTo(Point location)
        {
            if (ClientSize.IsEmpty)
                return;

            if (!Parent.Focused)
                return;

            if (!EnableDrawing)
                return;

            using (Graphics g = Parent.CreateGraphics())
            {
                if (bitmapNew == null)
                {
                    bitmapOld = new Bitmap(ClientSize.Width, ClientSize.Height, g);
                    bitmapNew = new Bitmap(ClientSize.Width, ClientSize.Height, g);
                }
                else
                {
                    // 在原位置恢复位图
                    g.DrawImage(bitmapOld, locationLast);
                }

                // 在新位置保存位图
                using (Graphics bmg = Graphics.FromImage(bitmapOld))
                {
                    bmg.CopyFromScreen(Parent.PointToScreen(location), Point.Empty, bitmapOld.Size);
                }

                // 绘新位置绘制
                using (Graphics bmg = Graphics.FromImage(bitmapNew))
                {
                    if (Draw != null)
                    {
                        BitbltPanelDrawEventArgs e = new BitbltPanelDrawEventArgs(bmg, this.ClientRectangle);
                        Draw(this, e);
                        if (e.Draw)
                        {
                            g.DrawImage(bitmapNew, location);
                        }
                    }
                }

                locationLast = location;
            }
        }
    }

    public class BitbltPanelDrawEventArgs : EventArgs
    {
        public Graphics Graphics { get; set; }
        public Rectangle Rectangle { get; set; }
        public bool Draw { get; set; }

        public BitbltPanelDrawEventArgs(Graphics g, Rectangle r)
        {
            this.Draw = true;
            this.Graphics = g;
            this.Rectangle = r;
        }
    }

    public delegate void BitbltPanelDrawEventHandler(object sender, BitbltPanelDrawEventArgs e);

}
